home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Internet Info 1994 March
/
Internet Info CD-ROM (Walnut Creek) (March 1994).iso
/
networking
/
ip
/
ka9q
/
MNetsrc.hqx
/
Mac TCP_IP Source v.33
/
fingserv.c
< prev
next >
Wrap
Text File
|
1989-03-01
|
10KB
|
410 lines
/*
*
* Finger support...
*
* Finger server routines. Written by Michael T. Horne - KA7AXD.
* Copyright 1988 by Michael T. Horne, All Rights Reserved.
* Permission granted for non-commercial use and copying, provided
* that this notice is retained.
*
*/
#include <stdio.h>
#include "global.h"
#include "config.h"
#include "mbuf.h"
#include "timer.h"
#include "netuser.h"
#include "tcp.h"
#include "finger.h"
struct tcb *fing_tcb = NULLTCB;
int16 finger_notify = 1;
finger1(argc, argv)
int argc;
char *argv[];
{
extern int32 ip_addr;
struct socket lsocket;
void fing_state();
void rcv_fing();
if (fing_tcb)
return;
/* start finger daemon */
lsocket.address = ip_addr;
if(argc < 2)
lsocket.port = FINGER_PORT;
else
lsocket.port = atoi(argv[1]);
fing_tcb = open_tcp(&lsocket, NULLSOCK, TCP_SERVER, 0, rcv_fing,
NULLVFP, fing_state, 0, (int *)NULL);
return;
}
/*
* Handle incoming finger connections and closures.
*
*/
void
fing_state(tcb,old,new)
struct tcb *tcb;
char old, /* old state */
new; /* new state */
{
struct finger *fing;
void snd_fing();
char *a;
#ifdef MAC
char *logtime();
#endif
switch(new){
case ESTABLISHED:
log(tcb,"open Finger");
fing = (struct finger *) malloc(sizeof(struct finger));
tcb->user = (char *)fing; /* Upward pointer */
fing->tcb = tcb; /* Downward pointer */
if (finger_notify) {
#ifdef MAC
printf("\007You're being fingered by %s! (%s)\n",
psocket(&tcb->conn.remote),logtime());
#else
printf("\007You're being fingered by %s!\n",
psocket(&tcb->conn.remote));
#endif
fflush(stdout);
}
return;
case CLOSED:
if (tcb == fing_tcb)
fing_tcb = NULLTCB;
if (tcb->user != NULLCHAR)
free(tcb->user);
del_tcp(tcb);
break;
}
}
/*
* Stop the finger server.
*/
finger0()
{
if (fing_tcb != NULLTCB) {
close_tcp(fing_tcb);
fing_tcb = NULLTCB;
}
return;
}
/*
* Send a short message on a tcb
*/
#ifndef CALLBK
static
#endif
sndmsg(tcb, msg)
struct tcb *tcb; /* tcb to send on */
char *msg; /* message to send */
{
struct mbuf *bp;
bp = qdata(msg,(int16)strlen(msg));
send_tcp(tcb,bp);
}
/*
* Finger receive upcall. This is the guts of the finger server.
* The user to finger is read from the socket. If only a newline
* is read, then send the remote host a list of all known 'users' on
* this system.
*/
void
rcv_fing(tcb, ccnt)
register struct tcb *tcb;
int16 ccnt;
{
struct finger *fing;
FILE *fuser;
struct mbuf *mbuf,
*bp;
char *buf,
*who,
*finger_file,
#ifndef MAC
*path,
#endif
ch,
temp[80],
user[80];
int cnt;
int size;
if ((fing = (struct finger *) tcb->user) == NULLFING) /* uh oh! */
return;
if(recv_tcp(tcb,&bp,FINGNAMELEN) == 0)
return;
if ((who = malloc(FINGNAMELEN + 1)) == NULL) {
free_p(bp);
return;
}
cnt = pullup(&bp, who, FINGNAMELEN); /* get 'user' name */
#ifdef MAC
free_p(bp); /* all done with bp */
/* null terminate what we got at */
buf = who;
while (*buf != '\015' && *buf != '\012'
&& *buf != '\0' && cnt) {
buf++;
cnt--;
}
*buf = '\0';
if (*who == '\0') {
/* give him a user listing */
#else
who[cnt] = '\0'; /* NULL terminate it */
free_p(bp); /* all done with bp */
if (*who == '\015' || *who == '\012') { /* give him a user listing */
#endif
int found = 0;
#ifdef MAC
finger_file = (char *) malloc(strlen(fingerpath) + 1
+ strlen(fingersuf) + 1);
if (finger_file == NULLCHAR) { /* uh oh... */
free(who); /* clean up */
close_tcp(tcb); /* close socket */
return;
}
/* create wildcard path to finger files */
sprintf(finger_file,"%s*%s", fingerpath, fingersuf);
sndmsg(tcb, "Known users on this system:\015\012");
for (filedir(finger_file, 0, user); user[0] != '\0';
filedir(finger_file, 1, user)) {
found++;
*index(user, '.') = '\0';
sprintf(temp, " %s\015\012", user);
sndmsg(tcb, temp);
}
if (!found)
sndmsg(tcb,"None!\015\012");
}
else {
/* give him a specific user listing */
#else
path = (char *) malloc(strlen(fingerpath) + strlen(fingersuf)
+ 2);
/* create wildcard path to finger files */
strcpy(path, fingerpath);
strcat(path, "*");
strcat(path, fingersuf);
sndmsg(tcb, "Known users on this system:\015\012");
for (filedir(path, 0, user); user[0] != '\0';
filedir (path, 1, user)) {
found++;
*index(user, '.') = '\0';
sprintf(temp, " %s\015\012", user);
sndmsg(tcb, temp);
}
if (!found)
sndmsg(tcb, "None!\015\012");
free(path);
}
else {
#endif
#ifdef CALLBK
if (*who == '%'){
mac_callbk(tcb,who);
free(who);
close_tcp(tcb);
return;
}
#endif
buf = who;
while (*buf != '\015' && *buf != '\012' && *buf != '\0')
buf++;
*buf = '\0';
/*
* Create path to user's finger file and see if the
* the file exists.
*/
finger_file = malloc(strlen(fingerpath) + strlen(who)
+ strlen(fingersuf) + 1);
if (finger_file == NULL) { /* uh oh... */
free(who); /* clean up */
close_tcp(tcb); /* close socket */
return;
}
#ifdef MAC
sprintf(finger_file, "%s%s%s", fingerpath, who, fingersuf);
if ((fuser = fopen(finger_file, "r")) == (FILE *) NULL) {
sprintf(temp, "User %s unknown on this system\015\012", who);
sndmsg(tcb, temp);
}
else { /* valid 'user' */
/*
* Here's a tricky routine to make sure we get
* everything in, including "\r\n". It's needed since
* UNIX files have only a '\n' for EOL. What is
* REALLY NEEDED is a standardized routine for filling
* mbufs from file input so that each server doesn't
* have to do it themselves! Ditto for emptying
* mbufs! The problem of "\r\n" doesn't rear its
* ugly head with MessyDOS, but with UNIX boxes...
*/
char nl = '\0'; /* newline flag */
char last = '\0'; /* last character from stream */
ch = fgetc(fuser); /* first get must be outside */
while (!feof(fuser)) {
size = tcb->window;
if ((mbuf = alloc_mbuf(size)) == NULLBUF) {
fclose(fuser); /* barf */
free(who); /* clean up */
free(finger_file);
close_tcp(tcb); /* close socket */
return;
}
buf = mbuf->data; /* pointer to buffer */
while(!feof(fuser) && size--) { /* loop */
/* if we see an isolated LF or a CR, insert CR followed by LF.
Ignore a LF that follows a CR in the file input stream. Ignore
control-Zs all the time. This approach should handle Mac, DOS,
and UNIX enviroments which may use LF, CR, or CRLF to indicate
end-of-line. In the packet, we always use CRLF. */
if (nl) {
*buf++ = '\012'; /* LF */
mbuf->cnt++;
nl--;
}
else switch(ch) {
case '\032': /* NO ^Z's! */
break;
case '\012': /* LF */
if (last == '\015')
break; /* ignore sometimes */
case '\015': /* CR */
*buf++ = '\015';
mbuf->cnt++;
nl++;
break;
default:
*buf++ = ch;
mbuf->cnt++;
break;
}
if (!nl) {
last = ch; /* save current character */
ch = fgetc(fuser); /* get next character */
}
}
/* we are at end of window size or at EOF, send what we have */
send_tcp(tcb, mbuf); /* send info */
}
/* we are at EOF, close file */
fclose(fuser);
}
} /* end of all-user or specific-user if-else block */
free(who); /* clean up */
free(finger_file);
close_tcp(tcb); /* close socket */
return;
#else
strcpy(finger_file, fingerpath);
strcat(finger_file, who);
strcat(finger_file, fingersuf);
if ((fuser = fopen(finger_file, "r")) == (FILE *) NULL) {
sprintf(temp, "User %s unknown on this system\015\012",
who);
sndmsg(tcb, temp);
}
else { /* valid 'user' */
char nl = '\0'; /* newline flag */
/*
* Here's a tricky routine to make sure we get
* everything in, including "\r\n". It's needed since
* UNIX files have only a '\n' for EOL. What is
* REALLY NEEDED is a standardized routine for filling
* mbufs from file input so that each server doesn't
* have to do it themselves! Ditto for emptying
* mbufs! The problem of "\r\n" doesn't rear its
* ugly head with MessyDOS, but with UNIX boxes...
*/
ch = fgetc(fuser); /* first get must be outside */
while (!feof(fuser)) {
size = tcb->window;
if ((mbuf = alloc_mbuf(size)) == NULL) {
fclose(fuser); /* barf */
free(who);
free(finger_file);
return;
}
buf = mbuf->data; /* pointer to buffer */
while(!feof(fuser) && size--) { /* loop */
if (nl) {
*buf++ = '\012';/* line feed */
mbuf->cnt++;
nl--;
}
else switch(ch) {
case '\032': /* NO ^Z's! */
break;
case '\012': /* ignore LF */
break;
case '\015': /* EOL */
nl++; /* fall thru */
default:
*buf++ = ch;
mbuf->cnt++;
break;
}
if (!nl)
ch = fgetc(fuser);
}
send_tcp(tcb, mbuf); /* send info */
}
fclose(fuser);
}
free(finger_file);
}
free(who);
close_tcp(tcb); /* close socket */
return;
#endif
}